import React, { useEffect, useState, useCallback } from 'react'
import { createPortal } from 'react-dom'
import { CheckCircle, XCircle, AlertCircle, Info, X, Loader, Zap } from 'lucide-react'

export type NotificationType = 'success' | 'error' | 'warning' | 'info' | 'loading' | 'ai_operation'

export interface NotificationProps {
  type: NotificationType
  title: string
  message?: string
  duration?: number
  onClose?: () => void
  action?: {
    label: string
    onClick: () => void
    variant?: 'primary' | 'secondary'
  }
  progress?: number
  persistent?: boolean
  dismissible?: boolean
}

export const Notification: React.FC<NotificationProps> = ({
  type,
  title,
  message,
  duration = 5000,
  onClose,
  action,
  progress,
  persistent = false,
  dismissible = true
}) => {
  const [isVisible, setIsVisible] = useState(true)
  const [currentProgress, setCurrentProgress] = useState(progress || 0)

  useEffect(() => {
    if (progress !== undefined) {
      setCurrentProgress(progress)
    }
  }, [progress])

  useEffect(() => {
    if (!persistent && duration > 0 && type !== 'loading') {
      const timer = setTimeout(() => {
        setIsVisible(false)
        onClose?.()
      }, duration)

      return () => clearTimeout(timer)
    }
  }, [duration, onClose, persistent, type])

  const handleClose = useCallback(() => {
    setIsVisible(false)
    onClose?.()
  }, [onClose])

  const icons = {
    success: <CheckCircle className="w-5 h-5 text-green-500" />,
    error: <XCircle className="w-5 h-5 text-red-500" />,
    warning: <AlertCircle className="w-5 h-5 text-yellow-500" />,
    info: <Info className="w-5 h-5 text-blue-500" />,
    loading: <Loader className="w-5 h-5 text-blue-500 animate-spin" />,
    ai_operation: <Zap className="w-5 h-5 text-purple-500" />
  }

  const bgColors = {
    success: 'bg-green-50 dark:bg-green-900/20 border-green-200 dark:border-green-800',
    error: 'bg-red-50 dark:bg-red-900/20 border-red-200 dark:border-red-800',
    warning: 'bg-yellow-50 dark:bg-yellow-900/20 border-yellow-200 dark:border-yellow-800',
    info: 'bg-blue-50 dark:bg-blue-900/20 border-blue-200 dark:border-blue-800',
    loading: 'bg-blue-50 dark:bg-blue-900/20 border-blue-200 dark:border-blue-800',
    ai_operation: 'bg-purple-50 dark:bg-purple-900/20 border-purple-200 dark:border-purple-800'
  }

  const textColors = {
    success: 'text-green-800 dark:text-green-200',
    error: 'text-red-800 dark:text-red-200',
    warning: 'text-yellow-800 dark:text-yellow-200',
    info: 'text-blue-800 dark:text-blue-200',
    loading: 'text-blue-800 dark:text-blue-200',
    ai_operation: 'text-purple-800 dark:text-purple-200'
  }

  if (!isVisible) return null

  return createPortal(
    <div className={`fixed top-4 right-4 z-50 max-w-sm w-full ${bgColors[type]} border rounded-lg shadow-lg p-4 transform transition-all duration-300 ease-in-out ${isVisible ? 'translate-x-0 opacity-100' : 'translate-x-full opacity-0'}`}>
      {/* Progress bar */}
      {type === 'loading' && currentProgress > 0 && (
        <div className="absolute top-0 left-0 w-full h-1 bg-gray-200 dark:bg-gray-700 rounded-t-lg overflow-hidden">
          <div
            className="h-full bg-blue-500 transition-all duration-300 ease-out"
            style={{ width: `${currentProgress}%` }}
          />
        </div>
      )}

      <div className="flex items-start gap-3">
        <div className="flex-shrink-0 mt-0.5">
          {icons[type]}
        </div>
        <div className="flex-1 min-w-0">
          <h4 className={`text-sm font-semibold ${textColors[type]}`}>
            {title}
          </h4>
          {message && (
            <p className={`mt-1 text-sm ${textColors[type]} opacity-90`}>
              {message}
            </p>
          )}

          {/* Action button */}
          {action && (
            <button
              onClick={() => {
                action.onClick()
                if (!persistent) {
                  handleClose()
                }
              }}
              className={`
                mt-2 px-3 py-1 text-sm font-medium rounded transition-colors
                ${action.variant === 'secondary'
                  ? 'bg-gray-100 text-gray-700 hover:bg-gray-200 dark:bg-gray-700 dark:text-gray-300 dark:hover:bg-gray-600'
                  : type === 'success' ? 'bg-green-100 text-green-800 hover:bg-green-200 dark:bg-green-800 dark:text-green-200 dark:hover:bg-green-700' :
                    type === 'error' ? 'bg-red-100 text-red-800 hover:bg-red-200 dark:bg-red-800 dark:text-red-200 dark:hover:bg-red-700' :
                    type === 'warning' ? 'bg-yellow-100 text-yellow-800 hover:bg-yellow-200 dark:bg-yellow-800 dark:text-yellow-200 dark:hover:bg-yellow-700' :
                    type === 'ai_operation' ? 'bg-purple-100 text-purple-800 hover:bg-purple-200 dark:bg-purple-800 dark:text-purple-200 dark:hover:bg-purple-700' :
                    'bg-blue-100 text-blue-800 hover:bg-blue-200 dark:bg-blue-800 dark:text-blue-200 dark:hover:bg-blue-700'
                }
              `}
            >
              {action.label}
            </button>
          )}
        </div>

        {/* Dismiss button */}
        {dismissible && (
          <button
            onClick={handleClose}
            className="flex-shrink-0 p-1 rounded hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors"
          >
            <X className="w-4 h-4 text-gray-500 dark:text-gray-400" />
          </button>
        )}
      </div>
    </div>,
    document.body
  )
}

export interface NotificationManager {
  show: (props: NotificationProps) => string
  hide: (id: string) => void
  update: (id: string, props: Partial<NotificationProps>) => void
  clear: () => void
}

interface NotificationItem extends NotificationProps {
  id: string
  container: HTMLElement
  root: any
}

export const createNotificationManager = (): NotificationManager => {
  const notifications = new Map<string, NotificationItem>()

  const generateId = () => Date.now().toString() + Math.random().toString(36).substring(2, 11)

  const show = (props: NotificationProps): string => {
    const id = generateId()
    const container = document.createElement('div')
    document.body.appendChild(container)

    const handleClose = () => {
      setTimeout(() => {
        if (document.body.contains(container)) {
          document.body.removeChild(container)
        }
        notifications.delete(id)
      }, 300)
    }

    const element = React.createElement(Notification, {
      ...props,
      onClose: () => {
        props.onClose?.()
        handleClose()
      }
    })

    // Use ReactDOM directly since it's already imported in main.tsx
    const ReactDOM = require('react-dom/client')
    const root = ReactDOM.createRoot(container)
    root.render(element)

    const notificationItem: NotificationItem = {
      id,
      ...props,
      container,
      root
    }

    notifications.set(id, notificationItem)
    return id
  }

  const hide = (id: string) => {
    const notification = notifications.get(id)
    if (notification) {
      notification.root.unmount()
      if (document.body.contains(notification.container)) {
        document.body.removeChild(notification.container)
      }
      notifications.delete(id)
    }
  }

  const update = (id: string, props: Partial<NotificationProps>) => {
    const notification = notifications.get(id)
    if (notification) {
      const updatedProps = { ...notification, ...props }
      const element = React.createElement(Notification, updatedProps)
      notification.root.render(element)
      notifications.set(id, { ...notification, ...updatedProps })
    }
  }

  const clear = () => {
    notifications.forEach((_, id) => hide(id))
  }

  return { show, hide, update, clear }
}

// Enhanced notification hook for React components
export const useNotification = () => {
  const [manager] = useState(() => createNotificationManager())

  const showSuccess = useCallback((title: string, message?: string, options?: Partial<NotificationProps>) => {
    return manager.show({ type: 'success', title, message, ...options })
  }, [manager])

  const showError = useCallback((title: string, message?: string, options?: Partial<NotificationProps>) => {
    return manager.show({ type: 'error', title, message, persistent: true, ...options })
  }, [manager])

  const showWarning = useCallback((title: string, message?: string, options?: Partial<NotificationProps>) => {
    return manager.show({ type: 'warning', title, message, ...options })
  }, [manager])

  const showInfo = useCallback((title: string, message?: string, options?: Partial<NotificationProps>) => {
    return manager.show({ type: 'info', title, message, ...options })
  }, [manager])

  const showLoading = useCallback((title: string, message?: string, options?: Partial<NotificationProps>) => {
    return manager.show({ type: 'loading', title, message, persistent: true, dismissible: false, ...options })
  }, [manager])

  const showAIOperation = useCallback((title: string, message?: string, options?: Partial<NotificationProps>) => {
    return manager.show({ type: 'ai_operation', title, message, ...options })
  }, [manager])

  const updateProgress = useCallback((id: string, progress: number) => {
    manager.update(id, { progress })
  }, [manager])

  const completeOperation = useCallback((loadingId: string, successMessage?: string, errorMessage?: string) => {
    if (successMessage) {
      manager.update(loadingId, { type: 'success', title: '操作完成', message: successMessage, persistent: false, dismissible: true })
      setTimeout(() => manager.hide(loadingId), 3000)
    } else if (errorMessage) {
      manager.update(loadingId, { type: 'error', title: '操作失败', message: errorMessage, persistent: true })
    } else {
      manager.hide(loadingId)
    }
  }, [manager])

  return {
    show: manager.show,
    hide: manager.hide,
    update: manager.update,
    clear: manager.clear,
    showSuccess,
    showError,
    showWarning,
    showInfo,
    showLoading,
    showAIOperation,
    updateProgress,
    completeOperation
  }
}

export default Notification